/*
 * OpenParts
 * A dynamic-loading components framework for GWT
 * Copyright (C) 2011 Christophe Bouthier  [chris{AT}binary-gastronome{DOT}fr]
 *
 * This work is partially based on work I have done at INRIA (http://www.inria.fr) 
 * in the context of the Qualipso European Project (http://qualipso.org/),
 * The work done at INRIA is Copyright (C) 2006-2011 INRIA
 *
 * This work is distributed under the LGPL version 3
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License version 3
 * as published by the Free Software Foundation. See the GNU
 * Lesser General Public License in LGPL.txt for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */
package fr.openparts.OpenParts.test.gwt.tests;

import com.google.gwt.dom.client.Document;
import com.google.gwt.dom.client.MetaElement;
import com.google.gwt.junit.client.GWTTestCase;

import fr.openparts.OpenParts.client.OPParams;
import fr.openparts.OpenParts.client.OPShell;
import fr.openparts.OpenParts.container.OPContainer;

/**
 * GWT tests for OPContainer.
 * 
 * @author Christophe Bouthier [chris{AT}binary-gastronome{DOT}fr]
 * @creation.date 24 January 2010
 */
public class OPContainerTestGwt extends GWTTestCase {

    private static final String PART_NAME = "dummyService_container";
    private static final String PART_RESOURCE = "dummyResource";
    private static final String PART_VIEW = "dummyView";
    private static final String PART_PARAMS = "dummyKey1, dummyValue1, dummyKey2, dummyValue2";
    private static final String PART_PARAMS_KEY_1 = "dummyKey1";
    private static final String PART_PARAMS_KEY_2 = "dummyKey2";
    private static final String PART_PARAMS_VALUE_1 = "dummyValue1";
    private static final String PART_PARAMS_VALUE_2 = "dummyValue2";
    
    private OPContainer container;
    private Document doc;
    private MetaElement metaPart;

    /**
     * Return the name of the tested GWT Module.
     * 
     * @see com.google.gwt.junit.client.GWTTestCase#getModuleName()
     */
    @Override
    public final String getModuleName() {
        return "fr.openparts.OpenParts.test.gwt.TestOpenParts";
    }
    
    /**
     * Called at the start of each test to set up the part.
     * 
     * @see com.google.gwt.junit.client.GWTTestCase#gwtSetUp()
     */
    @Override
    protected void gwtSetUp() throws Exception {
        super.gwtSetUp();
        container = new OPContainer(); 
        doc = Document.get();
        metaPart = doc.createMetaElement();
        doc.insertFirst(metaPart);
    }
    
    /**
     * Called at the end of each test to clean up the mess.
     * 
     * @see com.google.gwt.junit.client.GWTTestCase#gwtTearDown()
     */
    @Override
    protected final void gwtTearDown() throws Exception {
        super.gwtTearDown();
        doc.removeChild(metaPart);
    }
    
    /**
     * Test getting the part name. Should get the specific constant.
     */
    public final void testPartName() {
        metaPart.setName(OPContainer.PART_NAME_META_TAG);
        metaPart.setContent(PART_NAME);
        assertEquals("Part name should be the specific constant", PART_NAME, container.getPartName());
    }
    
    /**
     * Test getting the part name without part name meta-tag. Should raise an assertion error.
     */
    public final void testNullPartName() {
        if (assertionsAreEnabled()) {
            try {
                container.getPartName();
                fail("OPContainer should raise an assertion error when asking for part name without part name meta-tag.");
            } catch (AssertionError e) {
                assertTrue("Error should be an AssertionError", e instanceof AssertionError);
            }
        }
    }
    
    /**
     * Test getting the part resource. Should get the specific constant.
     */
    public final void testPartResource() {
        metaPart.setName(OPContainer.PART_RESOURCE_META_TAG);
        metaPart.setContent(PART_RESOURCE);
        assertEquals("Part resource should be the specific constant", PART_RESOURCE, container.getPartResource());
    }
    
    /**
     * Test getting the part resource without part resource meta-tag. Should get the default value, that is the part name.
     */
    public final void testNullPartResource() {
        metaPart.setName(OPContainer.PART_NAME_META_TAG);
        metaPart.setContent(PART_NAME);
        assertEquals("Part resource should be defaulted to part name", PART_NAME, container.getPartResource());
    }
    
    /**
     * Test getting the part resource without neither part resource nor part name meta-tags. Should raise an assertion error.
     */
    public final void testNullPartResourceName() {
        if (assertionsAreEnabled()) {
            try {
                container.getPartResource();
                fail("OPContainer should raise an assertion error when asking for part name without part name meta-tag.");
            } catch (AssertionError e) {
                assertTrue("Error should be an AssertionError", e instanceof AssertionError);
            }
        }
    }
    
    /**
     * Test getting the part view. Should get the specific constant.
     */
    public final void testPartView() {
        metaPart.setName(OPContainer.PART_VIEW_META_TAG);
        metaPart.setContent(PART_VIEW);
        assertEquals("Part view should be the specific constant", PART_VIEW, container.getPartView());
    }
    
    /**
     * Test getting the part view without part view meta-tag. Should get the default value, that is OPShell.ACTION_ROOT.
     */
    public final void testNullPartView() {
        assertEquals("Part view should be defaulted to OPShell.ACTION_ROOT", OPShell.ACTION_ROOT, container.getPartView());
    }
    
    /**
     * Test getting the part params. Should parse the string to find back all constants.
     */
    public final void testPartParams() {
        metaPart.setName(OPContainer.PART_PARAMS_META_TAG);
        metaPart.setContent(PART_PARAMS);
        final OPParams params = container.getPartParams();
        assertNotNull("params shouldn't be null", params);
        assertEquals("Params should have only 2 elements", 2, params.size());
        assertEquals("Value for first key should be as specified", PART_PARAMS_VALUE_1, params.getParamValue(PART_PARAMS_KEY_1));
        assertEquals("Value for second key should be as specified", PART_PARAMS_VALUE_2, params.getParamValue(PART_PARAMS_KEY_2));
    }
    
    /**
     *  Test getting the part params without part params meta-tag. Should get null.
     */
    public final void testNullPartParams() {
        assertNull("Params should be null without the meta-tag", container.getPartParams());
    }

    /**
     * Test getting the part params with invalid format. Should raise an assertion error.
     */
    public final void testInvalidPartParams() {
        if (assertionsAreEnabled()) {
            try {
                metaPart.setName(OPContainer.PART_PARAMS_META_TAG);
                metaPart.setContent("test,test,test");
                container.getPartParams();
                fail("OPContainer should raise an assertion error when asking for part name without part name meta-tag.");
            } catch (AssertionError e) {
                assertTrue("Error should be an AssertionError", e instanceof AssertionError);
            }
        }
    }
    
    /**
     * Check if assertions are enabled.
     * 
     * @return true if assertions are enabled, false otherwise
     */
    private final boolean assertionsAreEnabled() {
        try {
            assert false;
            return false;
        } catch (AssertionError e) {
            return true;
        }
    }
    
}
